package cn.itcast.shop.order.dao.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.shop.admin.stock.domain.Stock;
import cn.itcast.shop.cart.domain.CartItem;
import cn.itcast.shop.order.dao.OrderDao;
import cn.itcast.shop.order.domain.OrderItem;
import cn.itcast.shop.order.domain.Orders;
import cn.itcast.shop.order.exception.OrderException;
import cn.itcast.shop.product.domain.Product;
import cn.itcast.shop.utils.MonthDate;

/**
 * 订单模块Dao实现类
 */
@Repository("orderDao")
@Transactional
public class OrderDaoImpl implements OrderDao {

	/**
	 * 注入sessionFactory
	 */
	@Autowired
	private SessionFactory sessionFactory;

	/**
	 * 获得数据库连接对象
	 */
	public Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
	/**
	 * 加载订单项
	 */
	@Override
	public Set<OrderItem> loadOrderItem(String cartItemIds) throws OrderException {
		//分离购物车条目的ID号
		String[] ids = cartItemIds.split(",");
		Integer[] intIds = new Integer[ids.length];
		for (int i = 0; i < ids.length; i++) {
			//把ID号转换成int型
			intIds[i] = new Integer(ids[i]);
		}
		//创建查询方法连接
		Criteria criteria = getSession().createCriteria(CartItem.class);
		//添加查询条件
		criteria.add(Restrictions.in("cartItemId", intIds));
		@SuppressWarnings("unchecked")
		//获得购物车条目的集合
		List<CartItem> list = criteria.list();
		
		Set<OrderItem> setOrderItem = new HashSet<>();
		StringBuilder message = new StringBuilder();
		//遍历购物车条目
		for (CartItem cartItem : list) {
			OrderItem orderItem = new OrderItem();
			//获取购物车条目所对应的商品ID
			Product product = (Product) getSession().get(Product.class, cartItem.getPid());
			if(product.getQuantity() == 0 ){ //商品库存为0
				getSession().delete(cartItem); //库存为0就删除此购物车项
				message.append(" "+product.getPname()+" 库存为0，将删除此项 ");
			}else if(product.getQuantity() < cartItem.getQuantity()) { //库存不足
				cartItem.setQuantity(product.getQuantity());  //改变购物车数量为库存
				message.append(" "+product.getPname()+"库存最多只有"+product.getQuantity()+"件了 ");
				getSession().update(cartItem); //更新购物车数量
			}else {
				orderItem.setProduct(product);
				orderItem.setCount(cartItem.getQuantity());
				orderItem.setSubtotal(cartItem.getSubtotal().doubleValue());
				setOrderItem.add(orderItem);
			}
		}
		if(message.length()>0){
			throw new OrderException(message.toString());
		}
		return setOrderItem;
	}
	/**
	 * 创建订单
	 */
	@Override
	public void createOrder(Orders orders) {
		Set<OrderItem> setOrderItem = orders.getSetOrderItem();
		for (OrderItem orderItem : setOrderItem) {
			Integer orderQuantity = orderItem.getCount();
			Product product = orderItem.getProduct();
			Integer productQuantity = product.getQuantity();
			//更新商品数量
			product.setQuantity(productQuantity-orderQuantity);
			getSession().update(product);
		}
		getSession().save(orders);
	}

	@Override
	public int findCountByUid(Integer uid) {
		String hql = "select count(*) from Orders where uid=?";
		int count = ((Long) getSession().createQuery(hql).setParameter(0, uid).uniqueResult()).intValue();
		return count;
	}

	@Override
	public List<Orders> findByUid(Integer uid, int begin, int limit) {
		String hql = "from Orders where uid =? order by ordertime desc";
		@SuppressWarnings("unchecked")
		List<Orders> list = getSession().createQuery(hql).setParameter(0, uid).setFirstResult(begin)
				.setMaxResults(limit).list();
		if (list.size() > 0) {
			return list;
		} else {
			return null;
		}
	}

	@Override
	public Orders findByOid(String oid) {
		Orders order = (Orders) getSession().get(Orders.class, oid);
		return order;
	}

	@Override
	public void updateState(String oid, int i) {
		Orders order = (Orders) getSession().get(Orders.class, oid);
		order.setState(i);
	}

	@Override
	public List<Orders> findAll(int begin , int limit) {
		Query query = getSession().createQuery("from Orders order by ordertime desc");
		query.setFirstResult(begin);
		query.setMaxResults(limit);
		@SuppressWarnings("unchecked")
		List<Orders> list = query.list();
		return list;
	}

	@Override
	public int findAllCount() {
		String hql = "select count(*) from Orders";
		Long l = (Long) getSession().createQuery(hql).uniqueResult();
		return l.intValue();
	}

	@Override
	public List<OrderItem> findOrderItem(String oid) {
		String hql = "from OrderItem where oid = ?";
		@SuppressWarnings("unchecked")
		List<OrderItem> list = getSession().createQuery(hql).setParameter(0, oid).list();
		return list;
	}

	@Override
	public void createStock(String oid) {
		Orders orders = (Orders) getSession().get(Orders.class, oid);
		for(OrderItem orderItem : orders.getSetOrderItem()){
			Stock stock = new Stock();
			stock.setNum(1);//出库为1
			stock.setTockTime(new Date());
			stock.setUsername(orders.getUser().getName());
			stock.setOrderItem(orderItem);
			getSession().save(stock);
		}
	}

	@Override
	public void cancelOrder(String oid) {
		Orders orders = findByOid(oid);
		Set<OrderItem> setOrderItem = orders.getSetOrderItem();
		for (OrderItem orderItem : setOrderItem) {
			Integer orderQuantity = orderItem.getCount();
			Product product = orderItem.getProduct();
			Integer productQuantity = product.getQuantity();
			product.setQuantity(productQuantity+orderQuantity);
			getSession().update(product);
		}
	}

	@Override
	public List<Orders> findThisMonthZD(Integer uid,int begin , int limit ,String zddate) throws ParseException {
		String hql = "from Orders where uid =? and ordertime >= ? and ordertime <=? order by ordertime desc";
		@SuppressWarnings("unchecked")
		List<Orders> list = getSession().createQuery(hql).setParameter(0, uid)
				.setParameter(1, MonthDate.thisMonthFirthday(zddate))
				.setParameter(2, MonthDate.thisMonthLastday(zddate))
				.setFirstResult(begin).setMaxResults(limit).list();
		if (list.size() > 0) {
			return list;
		} else {
			return null;
		}
	}

	@Override
	public int findCountByDate(Integer uid, String zddate) throws ParseException {
		String hql = "select count(*) from Orders where uid =? and ordertime >= ? and ordertime <=? ";
		int count = ((Long) getSession().createQuery(hql).setParameter(0, uid)
				.setParameter(1, MonthDate.thisMonthFirthday(zddate))
				.setParameter(2, MonthDate.thisMonthLastday(zddate))
				.uniqueResult()).intValue();
		return count;
	}

}
